Split GtkProgressBar finalization
authorEmmanuele Bassi <ebassi@gnome.org>
Tue, 28 Jul 2020 10:43:32 +0000 (11:43 +0100)
committerEmmanuele Bassi <ebassi@gnome.org>
Tue, 28 Jul 2020 10:47:40 +0000 (11:47 +0100)
We're stopping activity mode when finalizing, which will change
accessible state; this will create a GtkATContext, and since GtkWidget
drops its GtkATContext on dispose(), we're going to end up leaking it on
the floor:

```
2,007 (64 direct, 1,943 indirect) bytes in 1 blocks are definitely lost in loss record 36,242 of 36,944
   at 0x483977F: malloc (vg_replace_malloc.c:307)
   by 0x5222105: g_malloc (gmem.c:106)
   by 0x523E222: g_slice_alloc (gslice.c:1025)
   by 0x523E261: g_slice_alloc0 (gslice.c:1051)
   by 0x534B398: g_type_create_instance (gtype.c:1849)
   by 0x53302EE: g_object_new_internal (gobject.c:1937)
   by 0x53312AF: g_object_new_valist (gobject.c:2262)
   by 0x532FEE8: g_object_new (gobject.c:1780)
   by 0x4B3F942: gtk_test_at_context_new (gtktestatcontext.c:107)
   by 0x491CC50: gtk_at_context_create (gtkatcontext.c:380)
   by 0x4BFEDA0: gtk_widget_accessible_get_at_context (gtkwidget.c:8127)
   by 0x4906079: gtk_accessible_get_at_context (gtkaccessible.c:83)
   by 0x490618F: gtk_accessible_update_state (gtkaccessible.c:137)
   by 0x4ACBA6D: gtk_progress_bar_act_mode_leave (gtkprogressbar.c:690)
   by 0x4ACB4F8: gtk_progress_bar_finalize (gtkprogressbar.c:564)
```

We're also unparenting widgets and changing styles, which is another
potential source of leaks and side effects.

gtk/gtkprogressbar.c

index 6255296ea93aefa30c00bb28a10af8b3cc8b1b71..bbc68861e1999d12d90f91b2a0ca69536d8f58bb 100644 (file)
@@ -154,6 +154,7 @@ static void gtk_progress_bar_get_property         (GObject        *object,
 static void     gtk_progress_bar_act_mode_enter   (GtkProgressBar *progress);
 static void     gtk_progress_bar_act_mode_leave   (GtkProgressBar *progress);
 static void     gtk_progress_bar_finalize         (GObject        *object);
+static void     gtk_progress_bar_dispose          (GObject        *object);
 static void     gtk_progress_bar_set_orientation  (GtkProgressBar *progress,
                                                    GtkOrientation  orientation);
 static void     gtk_progress_bar_direction_changed (GtkWidget        *widget,
@@ -173,6 +174,7 @@ gtk_progress_bar_class_init (GtkProgressBarClass *class)
 
   gobject_class->set_property = gtk_progress_bar_set_property;
   gobject_class->get_property = gtk_progress_bar_get_property;
+  gobject_class->dispose = gtk_progress_bar_dispose;
   gobject_class->finalize = gtk_progress_bar_finalize;
 
   widget_class->direction_changed = gtk_progress_bar_direction_changed;
@@ -556,19 +558,26 @@ gtk_progress_bar_new (void)
 }
 
 static void
-gtk_progress_bar_finalize (GObject *object)
+gtk_progress_bar_dispose (GObject *object)
 {
   GtkProgressBar *pbar = GTK_PROGRESS_BAR (object);
 
   if (pbar->activity_mode)
     gtk_progress_bar_act_mode_leave (pbar);
 
-  g_free (pbar->text);
-
   g_clear_pointer (&pbar->label, gtk_widget_unparent);
+  g_clear_pointer (&pbar->progress_widget, gtk_widget_unparent);
+  g_clear_pointer (&pbar->trough_widget, gtk_widget_unparent);
 
-  gtk_widget_unparent (pbar->progress_widget);
-  gtk_widget_unparent (pbar->trough_widget);
+  G_OBJECT_CLASS (gtk_progress_bar_parent_class)->dispose (object);
+}
+
+static void
+gtk_progress_bar_finalize (GObject *object)
+{
+  GtkProgressBar *pbar = GTK_PROGRESS_BAR (object);
+
+  g_free (pbar->text);
 
   G_OBJECT_CLASS (gtk_progress_bar_parent_class)->finalize (object);
 }